﻿using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace VASJ.Common
{
    public class Utils
    {
        #region Encrypt and Decrypt

        private static string Encrypt(string plainText, string passPhrase, string saltValue, string hashAlgorithm, int passwordIterations, string initVector, int keySize)
        {
            byte[] initVectorBytes = Encoding.ASCII.GetBytes(initVector);
            byte[] saltValueBytes = Encoding.ASCII.GetBytes(saltValue);

            byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);

            PasswordDeriveBytes password = new PasswordDeriveBytes(
                                                            passPhrase,
                                                            saltValueBytes,
                                                            hashAlgorithm,
                                                            passwordIterations);

            byte[] keyBytes = password.GetBytes(keySize / 8);

            RijndaelManaged symmetricKey = new RijndaelManaged();

            symmetricKey.Mode = CipherMode.CBC;

            ICryptoTransform encryptor = symmetricKey.CreateEncryptor(
                                                             keyBytes,
                                                             initVectorBytes);

            MemoryStream memoryStream = new MemoryStream();

            CryptoStream cryptoStream = new CryptoStream(memoryStream,
                                                         encryptor,
                                                         CryptoStreamMode.Write);
            cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);

            cryptoStream.FlushFinalBlock();

            byte[] cipherTextBytes = memoryStream.ToArray();

            memoryStream.Close();
            cryptoStream.Close();

            string cipherText = Convert.ToBase64String(cipherTextBytes);

            return cipherText;
        }

        private static string Decrypt(string cipherText, string passPhrase, string saltValue, string hashAlgorithm, int passwordIterations, string initVector, int keySize)
        {
            byte[] initVectorBytes = Encoding.ASCII.GetBytes(initVector);
            byte[] saltValueBytes = Encoding.ASCII.GetBytes(saltValue);

            byte[] cipherTextBytes = Convert.FromBase64String(cipherText);

            PasswordDeriveBytes password = new PasswordDeriveBytes(
                                                            passPhrase,
                                                            saltValueBytes,
                                                            hashAlgorithm,
                                                            passwordIterations);

            byte[] keyBytes = password.GetBytes(keySize / 8);

            RijndaelManaged symmetricKey = new RijndaelManaged();

            symmetricKey.Mode = CipherMode.CBC;

            ICryptoTransform decryptor = symmetricKey.CreateDecryptor(
                                                             keyBytes,
                                                             initVectorBytes);

            MemoryStream memoryStream = new MemoryStream(cipherTextBytes);

            CryptoStream cryptoStream = new CryptoStream(memoryStream,
                                                          decryptor,
                                                          CryptoStreamMode.Read);

            byte[] plainTextBytes = new byte[cipherTextBytes.Length];

            int decryptedByteCount = cryptoStream.Read(plainTextBytes,
                                                       0,
                                                       plainTextBytes.Length);

            memoryStream.Close();
            cryptoStream.Close();

            string plainText = Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount);

            return plainText;
        }

        public static string Encrypt(string originText)
        {
            string passPhrase = Definition.ENCRYPT_PASS_PHRASE;
            string saltValue = Definition.ENCRYPT_SALT_VALUE;
            string hashAlgorithm = Definition.ENCRYPT_HASH_ALGORITHM;
            int passwordIterations = Definition.ENCRYPT_PASSWORD_ITERATIONS;
            string initVector = Definition.ENCRYPT_INIT_VECTOR;
            int keySize = Definition.ENCRYPT_KEY_SIZE;

            string encryptedText = Encrypt(originText,
                                            passPhrase,
                                            saltValue,
                                            hashAlgorithm,
                                            passwordIterations,
                                            initVector,
                                            keySize);
            return encryptedText;
        }

        public static string Decrypt(string originText)
        {
            string passPhrase = Definition.ENCRYPT_PASS_PHRASE;
            string saltValue = Definition.ENCRYPT_SALT_VALUE;
            string hashAlgorithm = Definition.ENCRYPT_HASH_ALGORITHM;
            int passwordIterations = Definition.ENCRYPT_PASSWORD_ITERATIONS;
            string initVector = Definition.ENCRYPT_INIT_VECTOR;
            int keySize = Definition.ENCRYPT_KEY_SIZE;

            string decryptedText = string.Empty;
            try
            {
                decryptedText = Decrypt(originText,
                                            passPhrase,
                                            saltValue,
                                            hashAlgorithm,
                                            passwordIterations,
                                            initVector,
                                            keySize);
            }
            catch (Exception ex)
            {
                Logger.Log.Error(ex.Message);
            }

            return decryptedText;
        }


        #endregion

        #region Unicode
        public static bool IsVietnamese(string value)
        {
            char[] specialChars = Constants.VietnameseSpecialChars.ToCharArray();

            int indexOf = value.IndexOfAny(specialChars);
            if (indexOf == -1)
                return false;
            else return true;
        }

        #endregion
    }
}